package com.ch7;

import lombok.extern.slf4j.Slf4j;

import java.sql.Connection;
import java.util.concurrent.atomic.AtomicIntegerArray;

/**
 * @author woldier
 * @version 1.0
 * @description 享元模式 自定义数据连接池
 * @date 2023/5/16 13:32
 **/
@Slf4j(topic = "c.Thread")
public class Pool {
    private final int poolSize;

    /**
    *连接池
     */
    private Connection[] connections;

    /**
     * 状态原子数组
     * 0表示未使用1表示已使用
     */
    private AtomicIntegerArray array;

    /**
    *
    * description 初始化pool
    *
    * @param poolSize  池size
    * @return
    * @author: woldier
    * @date: 2023/5/16 13:42
    */
    public Pool(int poolSize) {
        this.poolSize = poolSize;
        this.connections = new CustomConnection[poolSize];
        this.array = new AtomicIntegerArray(poolSize);
        for (int i = 0; i < poolSize; i++) {
            connections[i] = new CustomConnection();
            array.set(i,0);
        }
    }

    /**
    *
    * description 从连接池中获取一个连接
    *

    * @return
    * @author: woldier
    * @date: 2023/5/16 13:45
    */

    public Connection get(){
        while (true){
            for (int i = 0; i < poolSize; i++) {
                if (array.compareAndSet(i,0,1)) {
                    //成功cas
                    log.debug("成功get connection");
                    return connections[i];
                }
            }
            /*若遍历了一次数组都没cas成功说明全部conn都被拿走了,那么sleep等待*/
            synchronized (this){
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    /**
    *
    * description 归还连接
    *
    * @param connection  从线程池中拿走的连接
    * @return boolean
    * @author: woldier
    * @date: 2023/5/16 13:56
    */

    public boolean giveBack(Connection connection){
        for (int i = 0 ; i < poolSize; i++){
            if(connection == connections[i]){
                log.debug("归还连接池");
                array.set(i,0);//这里不存在竞争
                synchronized (this){ // 环境阻塞线程
                    this.notifyAll();
                }
                return true;
            }
        }
        return false;
    }
}
